当界面全屏时,在顶部下拉时会显示statusbar的实现原理:
/frameworks/base/services/core/java/com/android/server/policy/PhoneWindowManager.java
// monitor for system gestures
mSystemGestures = new SystemGesturesPointerEventListener(context,
new SystemGesturesPointerEventListener.Callbacks() {
@Override
public void onSwipeFromTop() {
if (mStatusBar != null) {
requestTransientBars(mStatusBar);
}
}
@Override
public void onSwipeFromBottom() {
if (mNavigationBar != null && mNavigationBarPosition == NAV_BAR_BOTTOM) {
requestTransientBars(mNavigationBar);
}
}
@Override
public void onSwipeFromRight() {
if (mNavigationBar != null && mNavigationBarPosition == NAV_BAR_RIGHT) {
requestTransientBars(mNavigationBar);
}
}
@Override
public void onSwipeFromLeft() {
if (mNavigationBar != null && mNavigationBarPosition == NAV_BAR_LEFT) {
requestTransientBars(mNavigationBar);
}
}
@Override
public void onFling(int duration) {
if (mPowerManagerInternal != null) {
mPowerManagerInternal.powerHint(
PowerManagerInternal.POWER_HINT_INTERACTION, duration);
}
}
@Override
public void onDebug() {
// no-op
}
@Override
public void onDown() {
mOrientationListener.onTouchStart();
}
@Override
public void onUpOrCancel() {
mOrientationListener.onTouchEnd();
}
@Override
public void onMouseHoverAtTop() {
mHandler.removeMessages(MSG_REQUEST_TRANSIENT_BARS);
Message msg = mHandler.obtainMessage(MSG_REQUEST_TRANSIENT_BARS);
msg.arg1 = MSG_REQUEST_TRANSIENT_BARS_ARG_STATUS;
mHandler.sendMessageDelayed(msg, 500);
}
@Override
public void onMouseHoverAtBottom() {
mHandler.removeMessages(MSG_REQUEST_TRANSIENT_BARS);
Message msg = mHandler.obtainMessage(MSG_REQUEST_TRANSIENT_BARS);
msg.arg1 = MSG_REQUEST_TRANSIENT_BARS_ARG_NAVIGATION;
mHandler.sendMessageDelayed(msg, 500);
}
@Override
public void onMouseLeaveFromEdge() {
mHandler.removeMessages(MSG_REQUEST_TRANSIENT_BARS);
}
});
其中requestTransientBars(mStatusBar);就是要求显示statusbar.
我们看看/frameworks/base/services/core/java/com/android/server/policy/SystemGesturesPointerEventListener.java
/*
* Listens for system-wide input gestures, firing callbacks when detected.
* @hide
*/
public class SystemGesturesPointerEventListener implements PointerEventListener
在PhoneWindowManager会将SystemGesturesPointerEventListener进行
mWindowManagerFuncs.registerPointerEventListener(mSystemGestures);
mWindowManagerFuncs是WindowManagerService实现
/frameworks/base/services/core/java/com/android/server/wm/WindowManagerService.java
public class WindowManagerService extends IWindowManager.Stub
implements Watchdog.Monitor, WindowManagerPolicy.WindowManagerFuncs
@Override
public void registerPointerEventListener(PointerEventListener listener) {
mPointerEventDispatcher.registerInputEventListener(listener);
}
//这里建立了window manager的input channel
mPointerEventDispatcher = new PointerEventDispatcher(mInputManager.monitorInput(TAG_WM));
mPointerEventDispatcher为
/frameworks/base/services/core/java/com/android/server/wm/PointerEventDispatcher.java
应用也有自己的input channel,在WindowManagerService的addWindow
final boolean openInputChannels = (outInputChannel != null
&& (attrs.inputFeatures & INPUT_FEATURE_NO_INPUT_CHANNEL) == 0);
if (openInputChannels) {
win.openInputChannel(outInputChannel);
}
/frameworks/base/services/core/java/com/android/server/wm/WindowState.java
void openInputChannel(InputChannel outInputChannel) {
if (mInputChannel != null) {
throw new IllegalStateException("Window already has an input channel.");
}
String name = makeInputChannelName();
InputChannel[] inputChannels = InputChannel.openInputChannelPair(name);
mInputChannel = inputChannels[0];
mClientChannel = inputChannels[1];
mInputWindowHandle.inputChannel = inputChannels[0];
if (outInputChannel != null) {
mClientChannel.transferTo(outInputChannel);
mClientChannel.dispose();
mClientChannel = null;
} else {
// If the window died visible, we setup a dummy input channel, so that taps
// can still detected by input monitor channel, and we can relaunch the app.
// Create dummy event receiver that simply reports all events as handled.
mDeadWindowEventReceiver = new DeadWindowEventReceiver(mClientChannel);
}
mService.mInputManager.registerInputChannel(mInputChannel, mInputWindowHandle);
那底层事件是怎么传递到input channel,那就得看
frameworks/native/services/inputflinger/InputDispatcher.cpp
dispatchMotionLocked{
....
if (isPointerEvent) {
// Pointer event. (eg. touchscreen)
injectionResult = findTouchedWindowTargetsLocked(currentTime,
entry, inputTargets, nextWakeupTime, &conflictingPointerActions);
} else {
// Non touch event. (eg. trackball)
injectionResult = findFocusedWindowTargetsLocked(currentTime,
entry, inputTargets, nextWakeupTime);
}
....
if (isMainDisplay(entry->displayId)) {
addMonitoringTargetsLocked(inputTargets);
}
findTouchedWindowTargetsLocked 这里对应的就是应用的input channel,
addMonitoringTargetsLocked这个对应的就是window manager的input channel.
通过这段我们就知道产生事件的时候既会派发给应用window也会派发给window manager,window manager主要是处理system 的事件,比如显示statusbar,navigationbar.
关于input channel还有很多细节问题,要自己慢慢研读代码,这里只记录一个大概的代码流程
分享到:
相关推荐
例如,在全屏模式下,可以隐藏StatusBar以获得更大的显示空间,但仍然需要保留ActionBar供用户操作。通过`SYSTEM_UI_FLAG_FULLSCREEN`标志可以实现StatusBar的隐藏和显示。 在实际开发中,我们还需要注意不同...
在Android开发中,有时我们可能需要为特定场景禁用状态栏(StatusBar),比如为了实现全屏体验或特殊界面设计。然而,通常情况下,系统权限是不允许应用直接禁用statusBar的,尤其是对于没有获取到SYSTEM_ALERT_...
在Android开发中,状态栏(StatusBar)的管理是界面设计中的一个重要环节,它可以极大地影响到应用的用户体验。"Android-gm-statusbar状态栏透明工具类" 提供了一种方便的方式来处理状态栏的透明效果,使得开发者...
在Android应用开发过程中,有时为了实现特定的设计效果或界面需求,开发者可能需要隐藏某些系统组件,如ActionBar、NotificationBar、StatusBar、SystemBar、TitleBar等。本文将详细介绍这些组件的隐藏方法,并提供...
本文将深入探讨基于jQuery实现的下拉全屏导航菜单的知识点,包括其特点、原理、应用以及如何使用提供的源码。 首先,jQuery是一个流行的JavaScript库,它简化了DOM操作、事件处理、动画和Ajax交互。在“jquery下拉...
3. jQuery事件处理:利用jQuery的`hover`事件监听用户的鼠标悬停行为,当鼠标进入菜单项时,显示下拉菜单;离开时,隐藏下拉菜单。 ```javascript $('.nav li').hover(function() { $(this).children('.submenu')....
在本文中,我们将深入探讨如何使用编程语言来实现全屏显示,并且保留工具条,以便用户在全屏模式下依然能够进行必要的操作。 首先,我们要理解全屏显示的基本原理。在大多数操作系统中,全屏模式通常是通过改变窗口...
通过这种方式,可以在ASP.NET应用中轻松实现页面加载时的全屏显示效果。 #### 三、总结 本文介绍了如何使用ASP.NET实现页面加载时的全屏显示功能。通过对原始代码的理解与扩展,我们不仅了解了使用.NET框架启动...
在C++编程中,全屏显示是一个常见的需求,特别是在游戏开发、图形用户界面(GUI)设计或者演示程序中。本节我们将深入探讨如何在VC++环境下实现全屏显示功能,这对初学者来说是一次很好的实践机会。 首先,我们需要...
在实现全屏显示时,需要注意以下几点: * 需要在CMainFrame类中添加成员变量m_oldWndPlacement、m_bFullScreen和m_FullScreenRect,并在构造函数中对其进行初始化。 * 需要在资源编辑器中编辑菜单IDR_MAINFRAME,并...
【jQuery全屏大幅下拉菜单导航代码】是一个基于JavaScript库jQuery实现的网页导航栏特效,其特点是设计风格仿照微软的蓝色大气样式,并且能够覆盖整个屏幕,提供丰富的交互体验。这种类型的导航菜单在现代网页设计中...
总的来说,"VC++ 6.0多文档界面全屏显示代码源程序"是一个实用的示例,展示了如何在传统的Windows应用程序中实现全屏功能,这对于那些正在学习MFC或者需要为MDI应用程序添加全屏模式的开发者来说非常有价值。...
状态栏(StatusBar)是操作系统或应用程序用户界面中的一个重要组成部分,通常位于屏幕的顶部或底部,显示当前系统状态、时间、通知以及各种快捷操作。在Android系统中,StatusBar更是与用户体验密切相关,因为它...
下面我们将深入探讨Android全屏欢迎界面的实现原理和关键知识点。 1. **布局设计** - 全屏欢迎界面通常由一个全屏背景图和可能的Logo或应用名称组成。在`res/layout`目录下创建一个新的XML布局文件,例如`splash_...
当用户选择全屏模式时,程序可以将picture控件的尺寸设置为与显示器分辨率相同,从而实现无边框的全屏显示。为了提供更好的用户体验,全屏模式下还应考虑键盘快捷键的响应,以及在退出全屏时的界面恢复。 在...
在iPhone的Safari浏览器中实现全屏浏览可以让用户在查看网页内容时获得更沉浸式的体验。通常,Safari浏览器在浏览网页时会显示顶部的工具栏和底部的标签页栏,这占据了屏幕的一部分空间。全屏浏览则可以隐藏这些元素...
当用户点击图片时,JavaScript会调用浏览器提供的全屏API,如`requestFullscreen`,使得图片在全屏模式下展示。需要注意的是,不同的浏览器可能有不同的全屏API,因此我们需要进行兼容性处理,确保在各种浏览器上都...
标题和描述中提到的“flex全屏代码界面全屏”主要涉及的是在Flex框架下实现全屏显示的技术。Flex是一种开源框架,用于构建富互联网应用(RIA),可以在Flash Player或通过Adobe AIR部署到桌面。全屏功能是许多现代...
一个简单的Android注册界面,在注册时支持全屏显示,通过下列两句实现:getWindow().setFlags(WindowManager.LayoutParams.FLAG_FULLSCREEN, WindowManager.LayoutParams.FLAG_FULLSCREEN);隐去状态栏部分电池等图标...
"MFC用以实现全屏显示"这个标题表明我们要探讨的是如何利用MFC来创建一个应用程序,该程序能够在启动后自动切换到全屏模式。全屏显示在游戏、多媒体应用、演示文稿或任何需要沉浸式用户体验的场景中非常常见。下面...