当界面全屏时,在顶部下拉时会显示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的隐藏和显示。 在实际开发中,我们还需要注意不同...
5. **Notification Bar和StatusBar的区别**:状态栏(StatusBar)展示系统通知和图标,而通知栏(Notification Bar)是用户下拉状态栏时显示更详细的通知信息的区域。在某些情况下,可能需要隐藏通知栏以达到全屏...
在iOS开发过程中,有时会遇到应用在运行时无法全屏显示的问题,表现为屏幕四周出现黑边,这无疑会影响用户体验。本篇文章将详细讲解如何解决这一问题,让你的应用完美适应各种设备的屏幕尺寸。 首先,我们需要了解...
在Android应用开发中,`ActionBar`是Android 3.0(API级别11)引入的一个重要组件,它提供了一个统一的界面,用于显示应用程序的标识、操作和当前上下文。然而,为了支持低版本Android系统,开发者需要进行一些适配...
在移动应用开发中,用户界面(UI)的设计与交互是至关重要的部分,而状态栏和导航栏作为用户界面的关键元素,对于用户体验有着显著的影响。本文将深入探讨如何使用"控制状态栏和导航栏显示隐藏接口"来优化应用程序的...
1. **StatusBar**: 状态栏是Android手机屏幕顶部的一条横条,显示时间、电池状态、网络信号等信息,并提供滑动打开通知中心的入口。状态栏的源码中包含了对各种图标、指示器以及下拉菜单的管理。 2. **...
- **状态栏(Status Bar)**:显示系统的相关信息,如登录用户、当前时间、系统状态等。 - **命令字段(Command Field)**:允许用户直接输入业务代码或其他指令,快速访问系统功能。 **1.2 用户登录** - **客户...