Android Window纪要
来源:互联网 发布:网络玄幻小说经典语录 编辑:程序博客网 时间:2024/06/01 08:38
Window概念理解
在Andriod开发中经常提到Activity和View,而位于它们之间的Window却较少涉及。Window所表示的是一个抽象的概念,实际上所有View都是依附于Window之上的,包括Activity中的视图、Dialog中的视图以及Toast中的视图。另外View的事件分发也是由Window传递给View的。
Window的管理
Window是一个抽象类,其具体实现为PhoneWindow,Window通过WindowMaganer来管理,如添加、修改和删除等操作。WindowManager是一个接口,其具体实现类为WindowManagerImpl,有如下几个比较重要的方法:
@Overridepublic void addView(@NonNull View view, @NonNull ViewGroup.LayoutParams params) { applyDefaultToken(params); mGlobal.addView(view, params, mDisplay, mParentWindow);}@Overridepublic void updateViewLayout(@NonNull View view, @NonNull ViewGroup.LayoutParams params) { applyDefaultToken(params); mGlobal.updateViewLayout(view, params);}@Overridepublic void removeView(View view) { mGlobal.removeView(view, false);}@Overridepublic void removeViewImmediate(View view) { mGlobal.removeView(view, true);}
由上述源码可知这几个方法的内部实现是由WindowManagerGlobal实现的。
Window与Activity的关联
通过Activity源码可知,Activity实现了Window.Callback,该接口定义如下:
/** * API from a Window back to its caller. This allows the client to * intercept key dispatching, panels and menus, etc. */public interface Callback { /** * Called to process key events. At the very least your * implementation must call * {@link android.view.Window#superDispatchKeyEvent} to do the * standard key processing. * * @param event The key event. * * @return boolean Return true if this event was consumed. */ public boolean dispatchKeyEvent(KeyEvent event); /** * Called to process a key shortcut event. * At the very least your implementation must call * {@link android.view.Window#superDispatchKeyShortcutEvent} to do the * standard key shortcut processing. * * @param event The key shortcut event. * @return True if this event was consumed. */ public boolean dispatchKeyShortcutEvent(KeyEvent event); /** * Called to process touch screen events. At the very least your * implementation must call * {@link android.view.Window#superDispatchTouchEvent} to do the * standard touch screen processing. * * @param event The touch screen event. * * @return boolean Return true if this event was consumed. */ public boolean dispatchTouchEvent(MotionEvent event); /** * Called to process trackball events. At the very least your * implementation must call * {@link android.view.Window#superDispatchTrackballEvent} to do the * standard trackball processing. * * @param event The trackball event. * * @return boolean Return true if this event was consumed. */ public boolean dispatchTrackballEvent(MotionEvent event); /** * Called to process generic motion events. At the very least your * implementation must call * {@link android.view.Window#superDispatchGenericMotionEvent} to do the * standard processing. * * @param event The generic motion event. * * @return boolean Return true if this event was consumed. */ public boolean dispatchGenericMotionEvent(MotionEvent event); /** * Called to process population of {@link AccessibilityEvent}s. * * @param event The event. * * @return boolean Return true if event population was completed. */ public boolean dispatchPopulateAccessibilityEvent(AccessibilityEvent event); /** * Instantiate the view to display in the panel for 'featureId'. * You can return null, in which case the default content (typically * a menu) will be created for you. * * @param featureId Which panel is being created. * * @return view The top-level view to place in the panel. * * @see #onPreparePanel */ @Nullable public View onCreatePanelView(int featureId); /** * Initialize the contents of the menu for panel 'featureId'. This is * called if onCreatePanelView() returns null, giving you a standard * menu in which you can place your items. It is only called once for * the panel, the first time it is shown. * * <p>You can safely hold on to <var>menu</var> (and any items created * from it), making modifications to it as desired, until the next * time onCreatePanelMenu() is called for this feature. * * @param featureId The panel being created. * @param menu The menu inside the panel. * * @return boolean You must return true for the panel to be displayed; * if you return false it will not be shown. */ public boolean onCreatePanelMenu(int featureId, Menu menu); /** * Prepare a panel to be displayed. This is called right before the * panel window is shown, every time it is shown. * * @param featureId The panel that is being displayed. * @param view The View that was returned by onCreatePanelView(). * @param menu If onCreatePanelView() returned null, this is the Menu * being displayed in the panel. * * @return boolean You must return true for the panel to be displayed; * if you return false it will not be shown. * * @see #onCreatePanelView */ public boolean onPreparePanel(int featureId, View view, Menu menu); /** * Called when a panel's menu is opened by the user. This may also be * called when the menu is changing from one type to another (for * example, from the icon menu to the expanded menu). * * @param featureId The panel that the menu is in. * @param menu The menu that is opened. * @return Return true to allow the menu to open, or false to prevent * the menu from opening. */ public boolean onMenuOpened(int featureId, Menu menu); /** * Called when a panel's menu item has been selected by the user. * * @param featureId The panel that the menu is in. * @param item The menu item that was selected. * * @return boolean Return true to finish processing of selection, or * false to perform the normal menu handling (calling its * Runnable or sending a Message to its target Handler). */ public boolean onMenuItemSelected(int featureId, MenuItem item); /** * This is called whenever the current window attributes change. * */ public void onWindowAttributesChanged(WindowManager.LayoutParams attrs); /** * This hook is called whenever the content view of the screen changes * (due to a call to * {@link Window#setContentView(View, android.view.ViewGroup.LayoutParams) * Window.setContentView} or * {@link Window#addContentView(View, android.view.ViewGroup.LayoutParams) * Window.addContentView}). */ public void onContentChanged(); /** * This hook is called whenever the window focus changes. See * {@link View#onWindowFocusChanged(boolean) * View.onWindowFocusChanged(boolean)} for more information. * * @param hasFocus Whether the window now has focus. */ public void onWindowFocusChanged(boolean hasFocus); /** * Called when the window has been attached to the window manager. * See {@link View#onAttachedToWindow() View.onAttachedToWindow()} * for more information. */ public void onAttachedToWindow(); /** * Called when the window has been attached to the window manager. * See {@link View#onDetachedFromWindow() View.onDetachedFromWindow()} * for more information. */ public void onDetachedFromWindow(); /** * Called when a panel is being closed. If another logical subsequent * panel is being opened (and this panel is being closed to make room for the subsequent * panel), this method will NOT be called. * * @param featureId The panel that is being displayed. * @param menu If onCreatePanelView() returned null, this is the Menu * being displayed in the panel. */ public void onPanelClosed(int featureId, Menu menu); /** * Called when the user signals the desire to start a search. * * @return true if search launched, false if activity refuses (blocks) * * @see android.app.Activity#onSearchRequested() */ public boolean onSearchRequested(); /** * Called when an action mode is being started for this window. Gives the * callback an opportunity to handle the action mode in its own unique and * beautiful way. If this method returns null the system can choose a way * to present the mode or choose not to start the mode at all. * * @param callback Callback to control the lifecycle of this action mode * @return The ActionMode that was started, or null if the system should present it */ @Nullable public ActionMode onWindowStartingActionMode(ActionMode.Callback callback); /** * Called when an action mode has been started. The appropriate mode callback * method will have already been invoked. * * @param mode The new mode that has just been started. */ public void onActionModeStarted(ActionMode mode); /** * Called when an action mode has been finished. The appropriate mode callback * method will have already been invoked. * * @param mode The mode that was just finished. */ public void onActionModeFinished(ActionMode mode);}
其中常见的有如下几个回调:
public boolean dispatchTouchEvent(MotionEvent event);
public void onWindowFocusChanged(boolean hasFocus);
public void onAttachedToWindow();
public void onDetachedFromWindow();
由此可见,很多关于Window的回调都是在Activity中处理的,它们的关系非常紧密。
当Activity被创建时,会为该Activity创建一个Window对象,由于Activity实现了Window.Callback,因此对于Window的操作就会在Activity中回调。创建完Window后,就需要把Activity的视图附加到Window上了。这个过程的步骤如下:
1.Activity中的实现
/** * Set the activity content from a layout resource. The resource will be * inflated, adding all top-level views to the activity. * * @param layoutResID Resource ID to be inflated. * * @see #setContentView(android.view.View) * @see #setContentView(android.view.View, android.view.ViewGroup.LayoutParams) */public void setContentView(int layoutResID) { getWindow().setContentView(layoutResID); initWindowDecorActionBar();}
2.Activity把添加视图的任务交给Window来处理,而Window会先创建一个DecorView(是一个FrameLayout),DecorView包含一个ID为android.R.id.content的内容区,其实质也是一个FrameLayout。
3. 在Activity中经常调用的setContentView(int resId),就是把我们的视图添加到DecorView的内容区,也正因为如此,这个添加视图的方法不叫setView,而叫setContentView。添加完成后,Activity的onContentChanged被回调。
4. DecorView添加好视图后,还需要使用WindowMagager的addView方法将其添加到Window中。
5. 以上步骤之后,所添加的视图并不可见,当Activity执行onResume()之后,才会将DecorView设置为可见,这样用户才真正看到了Activity的视图并可以接收用户交互。
- Android Window纪要
- android NDK 开发纪要
- android百度地图纪要
- Android广播纪要
- Android 前置摄像头调试纪要
- Android进程间通信纪要
- Android坐标相关知识纪要
- Android USB Camera开发纪要
- Android Lint增量扫描实战纪要
- Android Window
- 为android开发安装ubuntu系统环境纪要
- Android开源框架GreenDao3.0使用纪要
- Android Starting Window(Preview Window)
- 返工纪要
- Spring纪要
- MVVM 纪要
- 知识纪要
- SQLite3纪要
- C# 后台生成Word表单
- 怎么调用函数求ln x?
- 分享一下在centos上搭建ngrok服务器的过程吧!
- Java网卡监控
- Linux终端常用快捷键 必看!
- Android Window纪要
- OnPaint()闪烁问题
- BZOJ 1025 分组背包 置换
- Java HttpURLConnection和HTTPClient的比较
- QComboBox美化
- 优雅的实现多类型列表的Adapter
- 【软件开发流程-1】可行性研究报告
- jenkins 使用
- d3.js学习笔记 -- 尺度